/*******************************************************************************
 * Copyright (c) 2012 Alexandr Tsvetkov.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Alexandr Tsvetkov - initial API and implementation
 * 
 * Project:
 *     TAO Library
 * 
 * File name:
 *     StoreHashSet.java
 *
 * License agreement:
 *
 * 1. This code is published AS IS. Author is not responsible for any damage that can be
 *    caused by any application that uses this code.
 * 2. Author does not give a garantee, that this code is error free.
 * 3. This code can be used in NON-COMMERCIAL applications AS IS without any special
 *    permission from author.
 * 4. This code can be modified without any special permission from author IF AND ONLY IF
 *    this license agreement will remain unchanged.
 * 5. SPECIAL PERMISSION for this code usage in COMMERCIAL application SHOULD be obtained
 *    from author.
 ******************************************************************************/
package ua.at.tsvetkov.data.stores;

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;

import ua.at.tsvetkov.util.Log;

/**
 * @author A.Tsvetkov 2011, http://tsvetkov.at.ua, al@ukr.net
 */
public class StoreHashSet {

	public HashSet<Externalizable>				data;
	private Class<? extends Externalizable>	aClass;
	private String										storeFileName;

	/**
	 * Создает хранилище данных в памяти и при необходимости сохраняет/восстанавливает в файле.
	 * 
	 * @param aClass название класса.
	 * @param storeFileName название файла для хранения данных.
	 */
	public StoreHashSet(Externalizable aClass, String storeFileName) {
		this.aClass = aClass.getClass();
		this.storeFileName = storeFileName;
		this.data = new HashSet<Externalizable>();
	}

	/**
	 * Добавляет объект для хранения.
	 * 
	 * @param object объект для хранения.
	 */
	public void add(Externalizable object) {
		if (object.getClass().isInstance(aClass)) {
			data.add(object);
		} else {
			Log.e("Object " + object + " is not instance of " + aClass.getName());
		}
	}

	/**
	 * Удаление объекта
	 * 
	 * @param object
	 */
	public void remove(Externalizable object) {
		data.remove(object);
	}

	/**
	 * Очистка массива данных
	 */
	public void clear() {
		data.clear();
	}

	/**
	 * Сохраняет данные в файл
	 */
	public void save() {
		ObjectOutputStream out = null;
		try {
			out = new ObjectOutputStream(new FileOutputStream(new File(storeFileName)));
			out.writeInt(data.size()); // Запись заголовка
			for (Externalizable ext : data) {
				ext.writeExternal(out);
			}
			out.flush();
			out.close();
			Log.v("Saved " + storeFileName);
		} catch (Exception e) {
			Log.e("Failed saving " + storeFileName, e);
		}
	}

	/**
	 * Загружает данные из файла
	 */
	public void load() {
		if (storeFileName == null || storeFileName.length() == 0) {
			return;
		}
		File file = new File(storeFileName);
		if (!file.exists()) {
			return;
		}
		ObjectInputStream in = null;
		try {
			in = new ObjectInputStream(new FileInputStream(new File(storeFileName)));
			int count = in.readInt();
			for (int i = 0; i < count; i++) {
				Externalizable ext = (Externalizable) aClass.newInstance();
				ext.readExternal(in);
				data.add(ext);
			}
			in.close();
			Log.v("Loaded " + storeFileName);
		} catch (Exception e) {
			Log.e("Failed loading data from " + storeFileName, e);
		}
	}

}
